package cloudspace.vm.javassist;

import java.util.List;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
import javassist.expr.Expr;
import cloudspace.vm.VM;
import cloudspace.vm.javassist.AbstractCommand.SignatureType;

/**
 * This is a command to add a field to a given class. Configuration files for
 * this class are specified as follows.
 * 
 * translate AddField <Class Name> <Field Type> <Name>
 * 
 * The class name specifies the name of the class to add the field to. Class
 * name can be a super type as well (in case you want to broaden the type of
 * class you want to add the field to). The field type is the type that the
 * field should be defined as. The name of the class will be the declared name
 * of the class.
 * 
 * @author mike
 * 
 */
public class AddField implements CommandInterface
{
	List<String> configArgs;

	/**
	 * generic constructor to create a new command.
	 * 
	 * @param arguments
	 */
	public AddField(List<String> args)
	{
		configArgs = args;
	}

	@Override
	public String getReplacement()
	{
		return configArgs.get(4).substring(1, configArgs.get(4).length() - 1);
	}

	@Override
	public String getSignature()
	{
		return configArgs.get(1);
	}

	@Override
	public SignatureType getSignatureType()
	{
		return SignatureType.STATICDEFINITION;
	}

	@Override
	public void translate(Expr call, boolean isSuper)
			throws MalformedCommandException, CannotCompileException
	{
		throw new MalformedCommandException("This command is not implemented");

	}

	@Override
	public void translate(CtMethod member, String expressionName)
			throws MalformedCommandException, CannotCompileException,
			MalformedCommandException
	{
		throw new MalformedCommandException("This command is not implemented");
		// member.addLocalVariable(name, type);

	}

	@Override
	public void translate(CtClass clazz) throws MalformedCommandException,
			CannotCompileException
	{
		
		try
		{
			CtClass superClazz = clazz.getSuperclass();
			while (superClazz != null)
			{
				if (superClazz.getName().equals(getSignature()))
				{
					CtClass clazz2;
					clazz2 = VM.currentVM().currentVM().getClassPool().get(configArgs.get(2));
					CtField field = new CtField(clazz2, configArgs.get(3), clazz);
					CtNewMethod.setter("set"+configArgs.get(3), field);
					CtNewMethod.getter("get"+configArgs.get(3), field);
					clazz.addField(field,getReplacement());
				}
				superClazz = superClazz.getSuperclass();
			}
		}
		catch (NotFoundException e)
		{
			e.printStackTrace();
		}

	}

}
